package main

import (
	"fmt"
	"sync"
	"time"
)

// BlockingQueue 是一个阻塞队列的结构体
type BlockingQueue struct {
	queue chan interface{}
	size  int
	mu    sync.Mutex
}

// NewBlockingQueue 创建一个新的阻塞队列
func NewBlockingQueue(size int) *BlockingQueue {
	return &BlockingQueue{
		queue: make(chan interface{}, size),
		size:  size,
	}
}

// Enqueue 向队列中添加一个元素，如果队列已满则阻塞
func (bq *BlockingQueue) Enqueue(item interface{}) error {
	// 使用带缓冲的通道，当队列满时会阻塞
	bq.queue <- item
	return nil
}

// Dequeue 从队列中取出一个元素，如果队列为空则阻塞
func (bq *BlockingQueue) Dequeue() (interface{}, error) {
	// 使用带缓冲的通道，当队列空时会阻塞
	item := <-bq.queue
	return item, nil
}

// Size 返回队列中当前元素的数量（非线程安全）
func (bq *BlockingQueue) Size() int {
	bq.mu.Lock()
	defer bq.mu.Unlock()
	return len(bq.queue)
}

// Capacity 返回队列的容量
func (bq *BlockingQueue) Capacity() int {
	return bq.size
}

func main() {
	// 创建一个容量为5的阻塞队列
	queue := NewBlockingQueue(5)

	// 启动生产者 goroutine
	go func() {
		for i := 0; i < 10; i++ {
			item := fmt.Sprintf("item-%d", i)
			fmt.Printf("Enqueueing %s\n", item)
			if err := queue.Enqueue(item); err != nil {
				fmt.Println("Error enqueueing:", err)
			}
			time.Sleep(time.Second) // 模拟生产时间
		}
	}()

	// 启动消费者 goroutine
	go func() {
		for i := 0; i < 10; i++ {
			item, err := queue.Dequeue()
			if err != nil {
				fmt.Println("Error dequeueing:", err)
				continue
			}
			fmt.Printf("Dequeueing %s\n", item)
			time.Sleep(1500 * time.Millisecond) // 模拟消费时间
		}
	}()

	// 防止 main goroutine 提前退出
	time.Sleep(15 * time.Second)
}
